package com.chenjiajin.jackson_test;

import com.chenjiajin.domain.Department;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Slf4j
public class TestPoJo implements Serializable {

    /**
     * json提供的对象
     */
    public static final ObjectMapper mapper = new ObjectMapper();


    public static void main(String[] args) {

        //toString
        System.err.println("-------------------------------------toString-----------------------------------------------");
        String str = "123";
        System.err.println("String = " + toString(str));  // String = 123

        Department pojo = new Department();
        pojo.setId(1L);
        pojo.setName("开发部");
        pojo.setSn("DEV");
        System.err.println("pojo = " + toString(pojo));  // pojo = {"id":1,"name":"开发部","sn":"DEV"}


        //toBean
        System.err.println("--------------------------------------toBean----------------------------------------------");
        System.err.println(toBean("123", String.class));

        String str2 = "{\"id\":1,\"name\":\"开发部\",\"sn\":\"DEV\"}";
        System.err.println("pojo = " + toBean(str2, Department.class));

        //toList
        System.err.println("--------------------------------------toList----------------------------------------------");
        List<Department> list = new ArrayList<>(Arrays.asList(new Department("aa"), new Department("bb"), new Department("cc")));
        String ListJsonStr = toString(list);
        System.err.println("ListJsonStr = " + ListJsonStr);
        List<Department> list2 = toList(ListJsonStr, Department.class);
        list2.forEach(System.err::println);


        //toMap
        System.err.println("--------------------------------------toMap----------------------------------------------");
        Department department = new Department(1L, "aa", "bb");
        String pojoJsonStr = toString(department);
        Map<String, String> map = toMap(pojoJsonStr, String.class, String.class);
        map.forEach((k, v) -> System.err.println("k = " + k + " v = " + v));
    }


    /**
     * 将对象转为json字符串
     */
    public static String toString(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj.getClass() == String.class) {
            return (String) obj;
        }
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("json序列化出错：" + obj, e);
            return null;
        }
    }


    /**
     * 将json字符串转为指定泛型的对象
     * 泛型不对的时候将出异常
     */
    public static <T> T toBean(String json, Class<T> tClass) {
        try {
            return mapper.readValue(json, tClass);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * 将json字符串转为指定泛型的list集合
     */
    public static <E> List<E> toList(String json, Class<E> eClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * 将json字符串转为指定泛型的map集合
     */
    public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * 将json字符串转为指定泛型的对象
     * 用于泛型里面还有一个泛型的情况下
     * 支持 泛型套泛型
     */
    public static <T> T nativeRead(String json, TypeReference<T> type) {
        try {
            return mapper.readValue(json, type);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

}